package gang.org.springframework.boot.context.annotation;

import gang.org.springframework.framework.io.GangUrlResource;
import lombok.SneakyThrows;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Consumer;

/**
 * @Author：gang.chen
 * @Date：2023/10/13 16:33
 */
public final class GangImportCandidates implements Iterable<String > {

    public final List<String> candidates;
    public static final String COMMENT_START = "#";
    public static final String LOCATION = "META-INF/spring/%s.imports";

    public GangImportCandidates(List<String> candidates){
        this.candidates = Collections.unmodifiableList(candidates);
    }

    @Override
    public Iterator<String> iterator() {
        return this.candidates.iterator();
    }


    public static GangImportCandidates load(Class<?> annotation, ClassLoader classLoader){

        ClassLoader classLoaderToUse = decideClassLoader(classLoader);

        String location = String.format(LOCATION, annotation.getName());

        Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);

        List<String> autoConfigurations = new ArrayList<>();

        while (urls.hasMoreElements()) {

            URL url = urls.nextElement();

            autoConfigurations.addAll(readAutoConfigurations(url));
        }
        return new GangImportCandidates(autoConfigurations);
    }

    public static ClassLoader decideClassLoader(ClassLoader classLoader){
        if (classLoader==null) {
            return GangImportCandidates.class.getClassLoader();
        }
        return classLoader;
    }

    @SneakyThrows
    public static Enumeration<URL> findUrlsInClasspath(ClassLoader classLoader, String location){
        return classLoader.getResources(location);
    }

    public static List<String> readAutoConfigurations(URL url){

        try(BufferedReader reader = new BufferedReader(new InputStreamReader(new GangUrlResource(url).getInputStream(), StandardCharsets.UTF_8))) {

            List<String> autoConfigurations = new ArrayList<>();
            String line;
            while ((line = reader.readLine()) != null){

                line = stripComment(line);
                line = line.trim();
                if (line.isEmpty()) {
                    continue;
                }
                autoConfigurations.add(line);
            }
            return autoConfigurations;

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    private static String stripComment(String line) {
        int commentStart = line.indexOf(COMMENT_START);
        if (commentStart == -1) {
            return line;
        }
        return line.substring(0, commentStart);
    }
}
